package com.yunbiao.ybbusstopplate.refactoring.ui.fengxian;

import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.blankj.utilcode.util.FileIOUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.UiMessageUtils;
import com.example.library_hy_advert.system.Cache;
import com.google.gson.reflect.TypeToken;
import com.yunbiao.ybbusstopplate.refactoring.Config;
import com.yunbiao.ybbusstopplate.refactoring.agreement.base.ProtocolParser;
import com.yunbiao.ybbusstopplate.refactoring.ui.dalian.ZHIDAParser;
import com.yunbiao.ybbusstopplate.refactoring.ui.yibin.ZHXPortAgreement;
import com.yunbiao.ybbusstopplate.refactoring.utils.L;
import com.yunbiao.ybbusstopplate.refactoring.utils.Utils;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import tp.xmaihh.serialport.SerialHelper;
import tp.xmaihh.serialport.bean.ComBean;

public class BASHITONGParser extends ProtocolParser {
    private static final String TAG = "BASHITONGParser";

    private static final String KEY_UP_LIST = "key_bashitong_up_list";
    private static final String KEY_DOWN_LIST = "key_bashitong_down_list";
    private static final String KEY_LAST_INDEX = "key_bashitong_last_index";
    private static final String KEY_LAST_INOUT = "key_bashitong_last_inout";
    private static final String KEY_LAST_DIRECTION = "key_bashitong_last_direction";
    private static final String KEY_LINE_NAME = "key_bashitong_line_name";


    private final LinkedHashMap<Integer, ZHIDAParser.Site> upMap = new LinkedHashMap<>();
    private final LinkedHashMap<Integer, ZHIDAParser.Site> downMap = new LinkedHashMap<>();

    @Override
    public void loadCache() {
        String string = Cache.getString(KEY_UP_LIST);
        Log.d(TAG, "KEY_UP_LIST: " + string);
        if(!TextUtils.isEmpty(string)){
            List<ZHIDAParser.Site> list = GsonUtils.fromJson(string,new TypeToken<List<ZHIDAParser.Site>>(){}.getType());
            upMap.clear();
            for (ZHIDAParser.Site site : list) {
                upMap.put(site.getIndex(),site);
            }
        }

        string = Cache.getString(KEY_DOWN_LIST);
        Log.d(TAG, "KEY_DOWN_LIST: " + string);
        if(!TextUtils.isEmpty(string)){
            List<ZHIDAParser.Site> list = GsonUtils.fromJson(string,new TypeToken<List<ZHIDAParser.Site>>(){}.getType());
            downMap.clear();
            for (ZHIDAParser.Site site : list) {
                downMap.put(site.getIndex(),site);
            }
        }

        String upDown;
        String lastDirectionStr = Cache.getString(KEY_LAST_DIRECTION);
        if(!TextUtils.isEmpty(lastDirectionStr)){
            upDown = lastDirectionStr;
        } else {
            upDown = "00";
        }

        String inOut = "00";
        String lastInOutStr = Cache.getString(KEY_LAST_INOUT);
        if(!TextUtils.isEmpty(lastInOutStr)){
            inOut = lastInOutStr;
        }

        int lastIndex = Cache.getInt(KEY_LAST_INDEX);

        String lineName = Cache.getString(KEY_LINE_NAME);

        L.d(TAG,"cache direction: " + upDown);
        L.d(TAG,"cache inOut: " + inOut);
        L.d(TAG,"cache lastIndex: " + lastIndex);
        L.d(TAG,"cache lineName: " + lineName);
        L.d(TAG,"cache upList: " + upMap.values());
        L.d(TAG,"cache downList: " + downMap.values());

        sendList(upDown);
        sendLineName(lineName);
        sendBroadSite(upDown,lastIndex,inOut);
        sendUpdateInfo();
        sendStartEndSiteAndTime();
    }

    private static final String KEY_UP_START_END_SITE = "key_bashitong_up_start_end_site";
    private static final String KEY_DOWN_START_END_SITE = "key_bashitong_down_start_end_site";
    private static final String KEY_UP_START_TIME = "key_bashitong_up_start_time";
    private static final String KEY_UP_END_TIME = "key_bashitong_up_end_time";
    private static final String KEY_DOWN_START_TIME = "key_bashitong_down_start_time";
    private static final String KEY_DOWN_END_TIME = "key_bashitong_down_end_time";

    private void sendStartEndSiteAndTime(){
        String upStartEndSite = Cache.getString(KEY_UP_START_END_SITE);
        String downStartEndSite = Cache.getString(KEY_DOWN_START_END_SITE);

        String upStartTime = Cache.getString(KEY_UP_START_TIME);
        String upEndTime = Cache.getString(KEY_UP_END_TIME);

        String downStartTime = Cache.getString(KEY_DOWN_START_TIME);
        String downEndTime = Cache.getString(KEY_DOWN_END_TIME);

        UiMessageUtils.getInstance().send(ZHIDAParser.Event.UPDATE_START_END.getType(),new String[]{
                upStartEndSite,downStartEndSite,
                upStartTime,upEndTime,
                downStartTime,downEndTime
        });
    }

    private void sendList(String upDown){
        if(TextUtils.equals("00",upDown)){
            ZHIDAParser.Site[] array = upMap.values().toArray(new ZHIDAParser.Site[0]);
            UiMessageUtils.getInstance().send(ZHIDAParser.Event.UPDATE_SITE_LIST.getType(),array);
            L.d(TAG,"sendList: 发送上行列表: " + Arrays.asList(array));

            sendStartEndSiteAndTime();
        } else if(TextUtils.equals("01",upDown)){
            ZHIDAParser.Site[] array = downMap.values().toArray(new ZHIDAParser.Site[0]);
            UiMessageUtils.getInstance().send(ZHIDAParser.Event.UPDATE_SITE_LIST.getType(),array);
            L.d(TAG,"sendList: 发送下行列表: " + Arrays.asList(array));

            sendStartEndSiteAndTime();
        }
    }

    private void sendBroadSite(String upDown,int index,String inOut){
        if(inOut.equals("01")){
            index += 1;

            if(upDown.equals("00")){
                int lastIndex = 0;
                for (Integer integer : upMap.keySet()) {
                    if(integer >= lastIndex){
                        lastIndex = integer;
                    }
                }
                if(index > lastIndex){
                    index = lastIndex;
                }
            } else if(upDown.equals("01")){
                int lastIndex = 0;
                for (Integer integer : downMap.keySet()) {
                    if(integer >= lastIndex){
                        lastIndex = integer;
                    }
                }
                if(index > lastIndex){
                    index = lastIndex;
                }
            }
        }

        Log.d(TAG, "sendBroadSite: " + upDown + " --- " + index + " --- " + inOut);
        if(TextUtils.equals("00",upDown)){
            if(!upMap.isEmpty()){
                ZHIDAParser.Site currSite = upMap.get(index);
                if(currSite != null){
                    UiMessageUtils.getInstance().send(ZHIDAParser.Event.BROAD_SITE.getType(),new Object[]{currSite,index,inOut,upDown});
                    L.d(TAG,"sendBroadSite: 发送上行报站: " + index + " --- " + inOut);
                }
            }
        } else if(TextUtils.equals("01",upDown)){
            if(!downMap.isEmpty()){
                ZHIDAParser.Site currSite = downMap.get(index);
                if(currSite != null){
                    UiMessageUtils.getInstance().send(ZHXPortAgreement.Event.BROAD_SITE.getType(),new Object[]{currSite,index,inOut,upDown});
                    L.d(TAG,"sendBroadSite: 发送下行报站: " + index + " --- " + inOut);
                }
            }
        }
    }

    public void sendLineName(String name){
        UiMessageUtils.getInstance().send(ZHIDAParser.Event.UPDATE_LINE_NAME.getType(),name);
        L.d(TAG,"sendLineName: 发送线路名: " + name);
    }

    public void sendUpdateInfo(){
        UiMessageUtils.getInstance().send(ZHIDAParser.Event.UPDATE_INFO.getType());
    }

    @Override
    public void analyzing(SerialHelper serialHelper, ComBean comBean) throws Throwable {
        try {
            byte[] bytes = comBean.bRec;

            String hex = Utils.bytesToHex(bytes);
            Log.e(TAG, "analyzing: " + hex);

            //开始符
            byte[] startBytes = Utils.subBytes(bytes,0,2);
            String startHex = Utils.bytesToHex(startBytes);
            if("7e43".equals(startHex)){
                return;
            }

            if(!"a55a".equals(startHex) && !"A55A".equals(startHex)){
                Log.e(TAG, "analyzing: " + hex);
                if (siteDataBuilder.length() > 0) {
                    siteDataBuilder.append(hex);
                    setLineSiteData(siteDataBuilder.toString());
                }
                return;
            }

            //协议长度
            byte[] dataLength = Utils.subBytes(bytes,2,2);
            //设备类型
            byte deviceType = bytes[4];
            //设备地址
            byte deviceAddress = bytes[5];
            if(deviceAddress != (byte)0x01){
                return;
            }

            //命令字
            byte orderByte = bytes[6];
            //协议状态
            byte statusByte = bytes[7];
            //保留字
            byte reserveByte = bytes[8];
            //序列号
            byte serialByte = bytes[9];
            //数据位
            byte[] dataBytes = Utils.subBytes(bytes,10,bytes.length -2 -2 -1 -1 -1 -1 -1 -1 -2);
            //校验位
            byte[] authCode = Utils.subBytes(bytes,bytes.length - 2, 2);
            Log.e(TAG, "开始符: " + Utils.bytesToHex(startBytes));
            Log.e(TAG, "协议长度: " + Utils.bytesToHex(dataLength));
            Log.e(TAG, "设备类型: " + Utils.byteToHex(deviceType) + " " + getDeviceType(deviceType));
            Log.e(TAG, "设备地址: " + Utils.byteToHex(deviceAddress));
            Log.e(TAG, "命令字: " + Utils.byteToHex(orderByte) + " " + getOrderName(orderByte));
            Log.e(TAG, "协议状态: " + Utils.byteToHex(statusByte));
            Log.e(TAG, "保留字: " + Utils.byteToHex(reserveByte));
            Log.e(TAG, "序列号: " + Utils.byteToHex(serialByte));
            Log.e(TAG, "数据位: " + Utils.bytesToHex(dataBytes));
            Log.e(TAG, "校验位: " + Utils.bytesToHex(authCode));
            Log.e(TAG, "设备子类型: " + Utils.byteToHex(dataBytes[0]) + " " + getDeviceChildType(dataBytes[0]));

            if(deviceType == (byte)0x05){
                byte deviceChildType = dataBytes[0];

                //车内走字屏
                if(deviceChildType == (byte)0x01){
                    //更新线路信息
                    if(orderByte == (byte)0x14){
                        dataBytes = Utils.subBytes(bytes,10,bytes.length -2 -2 -1 -1 -1 -1 -1 -1);
                        updateLineSiteData(dataBytes);
                    }
                    //更新车内LED屏进出站内容
                    else if(orderByte == (byte)0x02){
                        updateInOutContent(dataBytes);
                    }
                    else {
                        Log.d(TAG, "analyzing: 车内走字屏无需解析");
                    }
                }
                //头牌
                else if(deviceChildType == (byte)0x02){
                    //更新头腰尾牌显示内容
                    if(orderByte == (byte)0x01){
                        updateShowContent(dataBytes);
                    }
                    //更新车内LED屏进出站内容
                    else if(orderByte == (byte)0x02){
                        updateInOutContent(dataBytes);
                    }
                    //更新车内LED屏服务用语内容
                    else if(orderByte == (byte)0x03){
                        updateServiceContent(dataBytes);
                    }
                    else {
                        Log.d(TAG, "analyzing: 头牌不解析");
                    }
                }
                //腰牌
                else if(deviceChildType == (byte)0x03){
                    //更新头腰尾牌显示内容
                    if(orderByte == (byte)0x01){
                        updateShowContent(dataBytes);
                    }
                    //站级设置
                    else if(orderByte == (byte)0x04){
                        updateSiteLevelSetting(dataBytes);
                    }
                    //线路站点数据设置
                    else if(orderByte == (byte)0x14){
                        dataBytes = Utils.subBytes(bytes,10,bytes.length -2 -2 -1 -1 -1 -1 -1 -1);
                        updateLineSiteData(dataBytes);
                    }
                    else {
                        Log.d(TAG, "analyzing: 腰牌不解析");
                    }
                } else {
                    Log.d(TAG, "analyzing: 非头牌腰牌无需解析");
                }
            }
        } catch (Exception e){
            L.e(TAG, e);
            throw e;
        }
    }

    //更新头腰尾牌显示内容
    private void updateShowContent(byte[] dataBytes){
        List<String> strings = new ArrayList<>();

        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 1; i < dataBytes.length; i++) {
            String hex = Utils.byteToHex(dataBytes[i]);
            if(TextUtils.equals("00",hex)){
                String string = Utils.hexStringToString(stringBuilder.toString());
                stringBuilder.setLength(0);
                strings.add(string);
                continue;
            }
            stringBuilder.append(hex);
        }

        Log.d(TAG, "updateShowContent: " + strings);
    }
    //更新车内LED屏进出站内容
    private void updateInOutContent(byte[] dataBytes){
        // 01
        // 00
        // 13
        // 0303cfc2d2bbd5be20d5c5d4c634d7e9004e6578742073746f7020697320d5c5d4c634d7e9200032f0a54a19ffff067e430010000054494d45180b0b010a0815fb
        byte upDownByte = dataBytes[1];
        String upDown = Utils.byteToHex(upDownByte);

        byte siteIndexByte = dataBytes[2];
        int siteIndex = Utils.hex16to10(Utils.byteToHex(siteIndexByte));
        byte temperShowTime = dataBytes[3];
        byte inOutNameAndTemperShowNumber = dataBytes[4];
        byte[] contentBytes = Utils.subBytes(dataBytes,5,dataBytes.length - 5);
        String content = Utils.hexStringToString(Utils.bytesToHex(contentBytes));
        String inOut = content.contains("下一站") ? "01" : "00";

        List<String> strings = new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < contentBytes.length; i++) {
            String hex = Utils.byteToHex(contentBytes[i]);
            if(TextUtils.equals("00",hex)){
                String string = Utils.hexStringToString(stringBuilder.toString());
                stringBuilder.setLength(0);
                strings.add(string);
                continue;
            }
            stringBuilder.append(hex);
        }

        Log.d(TAG, "updateInOutContent : 上下行: " + Utils.byteToHex(upDownByte));
        Log.d(TAG, "updateInOutContent : 站序号: " + siteIndex);
        Log.d(TAG, "updateInOutContent : 温度显示停留时间: " + Utils.byteToHex(temperShowTime));
        Log.d(TAG, "updateInOutContent : 进出站内容及温度显示次数: " + Utils.byteToHex(inOutNameAndTemperShowNumber));
        Log.d(TAG, "updateInOutContent : 进出站: " + inOut);
        Log.d(TAG, "updateInOutContent : 更新车内LED屏进出站内容（中文）: " + Utils.bytesToHex(contentBytes));
        Log.d(TAG, "updateInOutContent : 更新车内LED屏进出站内容（中文）: " + strings);

        if(!TextUtils.equals(upDown,Cache.getString(KEY_LAST_DIRECTION,""))){
            sendList(upDown);
        }

        Cache.setString(KEY_LAST_DIRECTION,upDown);

        Cache.setInt(KEY_LAST_INDEX,siteIndex);

        Cache.setString(KEY_LAST_INOUT,inOut);

        sendBroadSite(upDown,siteIndex,inOut);
    }
    //更新车内LED屏服务用语内容
    private void updateServiceContent(byte[] dataBytes){
        byte temperShowTime = dataBytes[1];
        byte serviceContentAndTemperShowNumber = dataBytes[2];
        byte[] serviceContentBytes = Utils.subBytes(dataBytes,3,dataBytes.length - 3);

        Map<String, StringBuilder> hexMap = resolve(dataBytes);


        Log.d(TAG, "updateServiceContent : 温度显示停留时间: " + Utils.byteToHex(temperShowTime));
        Log.d(TAG, "updateServiceContent : 服务用语及温度显示次数: " + Utils.byteToHex(serviceContentAndTemperShowNumber));
        Log.d(TAG, "updateServiceContent : 更新车内LED屏服务用语内容（中文）: " + Utils.bytesToHex(serviceContentBytes));
        for (Map.Entry<String, StringBuilder> stringStringBuilderEntry : hexMap.entrySet()) {
            Log.d(TAG, "updateServiceContent: " + Utils.hexStringToString(stringStringBuilderEntry.getValue().toString()));
        }
    }
    //站级设置
    private void updateSiteLevelSetting(byte[] dataBytes){
        byte[] bytes = Utils.subBytes(dataBytes, 1, dataBytes.length - 3);
        String lineNameHex = Utils.bytesToHex(bytes);
        int upSiteCount = Utils.hex16to10(Utils.byteToHex(dataBytes[dataBytes.length - 2]));
        int downSiteCount = Utils.hex16to10(Utils.byteToHex(dataBytes[dataBytes.length - 1]));
        Log.d(TAG, "updateSiteLevelSetting: lineNameHex: " + lineNameHex);
        Log.d(TAG, "updateSiteLevelSetting: upSiteCount: " + upSiteCount);
        Log.d(TAG, "updateSiteLevelSetting: downSiteCount: " + downSiteCount);
    }

    private final AtomicInteger upSiteCount = new AtomicInteger(0);
    private final AtomicInteger downSiteCount = new AtomicInteger(0);
    private final StringBuilder siteDataBuilder = new StringBuilder();
    //线路站点数据设置
    private void updateLineSiteData(byte[] dataBytes){
        siteDataBuilder.append(Utils.bytesToHex(dataBytes));

        setLineSiteData(siteDataBuilder.toString());
    }

    private void setLineSiteData(String data){
        boolean isUpComplete = false;
        boolean isDownComplete = false;
        byte[] bytes = Utils.hexToByteArray(data);
        Map<String, StringBuilder> hexMap = resolve(bytes);
        for (Map.Entry<String, StringBuilder> stringStringBuilderEntry : hexMap.entrySet()) {
            switch (stringStringBuilderEntry.getKey()) {
                case "00":
                    String lineName = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    if(lineName.contains(",")){
                        lineName = lineName.split(",")[0];
                    }
                    Log.d(TAG, "线路名: " + stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "线路名: " + lineName);

                    Cache.setString(KEY_LINE_NAME,lineName);
                    sendLineName(lineName);
                    break;
                case "01":
                    String siteCount = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "站点个数: " + stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "站点个数: " + siteCount);

                    String[] split1 = siteCount.split(",");
                    if(split1.length >= 2){
                        upSiteCount.set(Integer.parseInt(split1[0]));
                        downSiteCount.set(Integer.parseInt(split1[1]));
                    } else {
                        upSiteCount.set(Integer.parseInt(split1[0]));
                    }
                    Log.d(TAG, "setLineSiteData:  "+ upSiteCount.get() + " --- " + downSiteCount.get());
                    break;
                case "02": {
                    Log.d(TAG, "上行站点列表（中文）: " + stringStringBuilderEntry.getValue().toString());
                    String upLineData = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    String[] split = upLineData.split(",");
                    Log.d(TAG, "上行站点列表（中文）: " + Arrays.toString(split));

                    upMap.clear();
                    for (int i = 0; i < split.length; i++) {
                        int siteIndex = i + 1;
                        upMap.put(siteIndex,new ZHIDAParser.Site(siteIndex,split[i],""));
                    }
                    isUpComplete = upMap.size() == upSiteCount.get();

                    Cache.remove(KEY_UP_START_END_SITE);
                    Cache.setString(KEY_UP_START_END_SITE,split[0] + " --> " + split[split.length - 1]);

                    if (isUpComplete && isDownComplete) {
                        siteDataBuilder.setLength(0);
                        Cache.remove(KEY_LAST_DIRECTION);
                        Cache.remove(KEY_LAST_INOUT);
                        Cache.remove(KEY_LAST_INDEX);

                        Cache.remove(KEY_UP_START_TIME);
                        Cache.remove(KEY_UP_END_TIME);
                        Cache.remove(KEY_DOWN_START_TIME);
                        Cache.remove(KEY_DOWN_END_TIME);

                        Cache.setString(KEY_UP_LIST, GsonUtils.toJson(upMap.values()));
                        Cache.setString(KEY_DOWN_LIST, GsonUtils.toJson(downMap.values()));

                        sendList("00");
                        sendStartEndSiteAndTime();
                    }
                    break;
                }
                case "03": {
                    Log.d(TAG, "下行站点列表（中文）: " + stringStringBuilderEntry.getValue().toString());
                    String downLineData = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    String[] split = downLineData.split(",");
                    Log.d(TAG, "下行站点列表（中文）: " + Arrays.toString(split));

                    downMap.clear();
                    for (int i = 0; i < split.length; i++) {
                        int siteIndex = i + 1;
                        downMap.put(siteIndex,new ZHIDAParser.Site(siteIndex,split[i],""));
                    }
                    isDownComplete = downMap.size() == downSiteCount.get();

                    Cache.remove(KEY_DOWN_START_END_SITE);
                    Cache.setString(KEY_DOWN_START_END_SITE,split[0] + " --> " + split[split.length - 1]);

                    if (isUpComplete && isDownComplete) {
                        siteDataBuilder.setLength(0);
                        Cache.remove(KEY_LAST_DIRECTION);
                        Cache.remove(KEY_LAST_INOUT);
                        Cache.remove(KEY_LAST_INDEX);

                        Cache.remove(KEY_UP_START_TIME);
                        Cache.remove(KEY_UP_END_TIME);
                        Cache.remove(KEY_DOWN_START_TIME);
                        Cache.remove(KEY_DOWN_END_TIME);

                        Cache.setString(KEY_UP_LIST, GsonUtils.toJson(upMap.values()));
                        Cache.setString(KEY_DOWN_LIST, GsonUtils.toJson(downMap.values()));

                        sendList("00");
                        sendStartEndSiteAndTime();
                    }
                    break;
                }
                case "04": {
                    String content = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "上行站点列表（英文）: " + content);
                    String[] split = content.split(",");
                    for (int i = 0; i < split.length; i++) {
                        int siteIndex = i + 1;
                        ZHIDAParser.Site site = upMap.get(siteIndex);
                        if(site != null){
                            site.setEnName(split[i]);
                        }
                    }
                    break;
                }
                case "05": {
                    String content = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "下行站点列表（英文）: " + content);
                    String[] split = content.split(",");
                    for (int i = 0; i < split.length; i++) {
                        int siteIndex = i + 1;
                        ZHIDAParser.Site site = downMap.get(siteIndex);
                        if(site != null){
                            site.setEnName(split[i]);
                        }
                    }
                    break;
                }
                case "06":
                    String startEndTime = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "线路首末班时间: " + stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "线路首末班时间: " + startEndTime);
                    if(!TextUtils.isEmpty(startEndTime) && startEndTime.contains(",")){
                        //05:30,22:00,06:35,23:16
                        String[] split = startEndTime.split(",");
                        if(split.length >= 4){
                            Cache.setString(KEY_UP_START_TIME,split[0]);
                            Cache.setString(KEY_UP_END_TIME,split[1]);
                            Cache.setString(KEY_DOWN_START_TIME,split[2]);
                            Cache.setString(KEY_DOWN_START_TIME,split[3]);
                        } else if(split.length >= 2){
                            Cache.setString(KEY_UP_START_TIME,split[0]);
                            Cache.setString(KEY_UP_END_TIME,split[1]);
                        }
                    }

                    sendStartEndSiteAndTime();
                    break;
                case "07":
                    String companyName = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "线路所属运营公司: " + stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "线路所属运营公司: " + companyName);
                    if(companyName == null){
                        companyName = "";
                    }
                    Cache.setString(Config.Key.COMPANY_NAME.name(),companyName);
                    sendUpdateInfo();
                    break;
                case "08":
                    String phoneNumber = Utils.hexStringToString(stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "调度室电话: " + stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "调度室电话: " + phoneNumber);
                    if(phoneNumber == null){
                        phoneNumber = "";
                    }
                    Cache.setString(Config.Key.PHONE_NUMBER.name(),phoneNumber);
                    sendUpdateInfo();
                    break;
                case "09":
                    Log.d(TAG, "票价: " + stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "票价: " + Utils.hexStringToString(stringStringBuilderEntry.getValue().toString()));
                    break;
                case "0a":
                    Log.d(TAG, "车牌号: " + stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "车牌号: " + Utils.hexStringToString(stringStringBuilderEntry.getValue().toString()));
                    break;
                case "0b":
                    Log.d(TAG, "车自编号: " + stringStringBuilderEntry.getValue().toString());
                    Log.d(TAG, "车自编号: " + Utils.hexStringToString(stringStringBuilderEntry.getValue().toString()));
                    break;
            }
        }
    }

    private Map<String,StringBuilder> resolve(byte[] dataBytes){
        Map<String,StringBuilder> hexMap = new HashMap<>();
        String type = "";
        for (int i = 1; i < dataBytes.length; i++) {
            String hex = Utils.byteToHex(dataBytes[i]);
            if(TextUtils.isEmpty(type)){
                type = hex;
                hexMap.put(type,new StringBuilder());
            } else if(TextUtils.equals("00",hex)){
                type = "";
            } else {
                StringBuilder stringBuilder = hexMap.get(type);
                if(stringBuilder == null){
                    stringBuilder = new StringBuilder();
                    hexMap.put(type,stringBuilder);
                }
                stringBuilder.append(hex);
            }
        }
        return hexMap;
    }

    private String getDeviceType(byte deviceTypeByte){
        //设备类型
        //0x01 DVR
        //0x02 POS机
        //0x03 投币票箱
        //0x04 MP3语音报站终端
        //0x05 车载电子显示屏（四牌）
        //0x06 客流统计设备
        switch (deviceTypeByte) {
            case (byte)0x01:
                return "DVR";
            case (byte)0x02:
                return "POS机";
            case (byte)0x03:
                return "投币票箱";
            case (byte)0x04:
                return "MP3语音报站终端";
            case (byte)0x05:
                return "车载电子显示屏（四牌）";
            case (byte)0x06:
                return "客流统计设备";
            default:
                return "未知";
        }
    }

    private String getOrderName(byte orderByte) {
        //协议命令字
        //0x00 1.获取硬件厂商名称     需要时发送
        //     2.获取硬件型号
        //     3.获取硬件GUID
        //     4.获取硬件当前的软件版本号
        //     5.获取线路文件信息
        //0x01 更新头腰尾牌内容     线路切换或上下行变化时发送
        //0x02 更新车内LED屏进出站内容   车辆进出站时发送
        //0x03 更新车内LED屏服务用语内容   服务用语播放时发送
        //0x04 站级设置   线路切换或上下行变化
        //0x11 更新新版头腰尾牌内容   线路切换或上下行变化时发送
        //0x14 线路站点数据设置   线路切换时发送
        //0x0A 通过终端透传给车载LED屏的数据   需要时发送
        switch (orderByte) {
            case (byte)0x00:
                return "获取硬件相关信息";
            case (byte)0x01:
                return "更新头腰尾牌内容";
            case (byte)0x02:
                return "更新车内LED屏进出站内容";
            case (byte)0x03:
                return "更新车内LED屏服务用语内容";
            case (byte)0x04:
                return "站级设置";
            case (byte)0x11:
                return "更新新版头腰尾牌内容";
            case (byte)0x14:
                return "线路站点数据设置";
            case (byte)0x0A:
                return "通过终端透传给车载LED屏的数据";
            default:
                return "未知";
        }
    }

    private String getDeviceChildType(byte deviceChildType){
        //设备子类型
        //0x01 车内走字屏
        //0x02 头牌
        //0x03 腰牌
        //0x04 尾牌
        //0x05 东方明珠电视
        switch (deviceChildType) {
            case (byte)0x01:
                return "车内走字屏";
            case (byte)0x02:
                return "头牌";
            case (byte)0x03:
                return "腰牌";
            case (byte)0x04:
                return "尾牌";
            case (byte)0x05:
                return "东方明珠电视";
            default:
                return "未知";
        }
    }

    public void test(){
        new Thread(() -> {
            File file = new File(Environment.getExternalStorageDirectory(),"test2.txt");

            List<String> strings = FileIOUtils.readFile2List(file);
            for (String string : strings) {
                if(string.contains("←◆")){
                    String[] split = string.split("←◆");
                    String hex = split[1];
                    hex = hex.replaceAll(" ", "");
                    byte[] bytes = Utils.hexToByteArray(hex);
                    try {
                        analyzing(null,new ComBean("",bytes,bytes.length));
                    } catch (Throwable e) {
                        Log.e(TAG, "test: ", e);
                    }
                }
            }
        }).start();
    }

    public void test1(){
        new Thread(() -> {
//            File file = new File(Environment.getExternalStorageDirectory(),"test.txt");

//            List<String> strings = FileIOUtils.readFile2List(file);
            
            String[] strings = new String[]{
                    "02:33:28.779 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a0d0005010b000003024923",
                            "02:33:29.378 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a360005010100007803b7eec6d6bfeccfdf2d3ec4cfc7c5c6fbb3b5d5be004e616e7169616f204275732053746174696f6e003f27",
                            "02:33:29.899 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a360005010100007902b7eec6d6bfeccfdf2d3ec4cfc7c5c6fbb3b5d5be004e616e7169616f204275732053746174696f6e00668b",
                            "02:33:30.679 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a160005010100007a04b7eec6d6bfeccfdf0056ec",
                            "02:33:31.531 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a4e0005011100007b02b7eec6d6bfeccfdf0000c9f2b6c5b9abc2b7005368656e6475204869676877617900c4cfc7c5c6fbb3b5d5be004e616e716961",
                            "02:33:31.551 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---6f204275732053746174696f6e001c2b",
                            "02:33:32.033 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a4e0005011100007c03b7eec6d6bfeccfdf0000c9f2b6c5b9abc2b7005368656e6475204869676877617900c4cfc7c5c6fbb3b5d5be004e616e716961",
                            "02:33:32.052 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---6f204275732053746174696f6e007b04",
                            "02:33:32.578 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a4e0005011100007d04b7eec6d6bfeccfdf0000c9f2b6c5b9abc2b7005368656e6475204869676877617900c4cfc7c5c6fbb3b5d5be004e616e716961",
                            "02:33:32.598 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---6f204275732053746174696f6e00cfe5",
                            "02:33:33.614 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a4a0205011400007e0100b7eec6d6bfeccfdf2c20000131332c31330002c4cfc7c5c6fbb3b5d5be2ccdfbd4b0c2b72cbdf0baa3b9abc2b72cb6a8bfb5",
                            "02:33:33.647 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: sendList: 发送上行列表: [Site{index=1, chName='南桥汽车站', enName=''}, Site{index=2, chName='望园路', enName=''}, Site{index=3, chName='金海公路', enName=''}, Site{index=4, chName='定', enName=''}]",
                            "02:33:33.650 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: sendLineName: 发送线路名: 奉浦快线",
                            "02:33:33.678 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---c2b72ccfcdc6d6c2b72cd0e3d6f1c2b72cc7e5c0cac2b72cbdf0b4f3b9abc2b72cc6ebcfcd2cc4cfd0d0b8dbc2b72cbdf0bbe32cc2b3c4cfc2b72cc9f2b6",
                            "02:33:33.742 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---c5b9abc2b70003c9f2b6c5b9abc2b72cc2b3c4cfc2b72cbdf0bbe32cc4cfd0d0b8dbc2b72cc6ebcfcd2cbdf0b4f3b9abc2b72cc7e5c0cac2b72cd0e3d6f1",
                            "02:33:33.806 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---c2b72ccfcdc6d6c2b72cb6a8bfb5c2b72cbdf0baa3b9abc2b72ccdfbd4b0c2b72cc4cfc7c5c6fbb3b5d5be00044e616e7169616f20427573205374617469",
                            "02:33:33.871 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---6f6e2c57616e677975616e20526f61642c4a696e68616920486967687761792c44696e676b616e6720526f61642c5869616e707520526f61642c5869757a",
                            "02:33:33.937 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---687520526f61642c51696e676c616e6720526f61642c4a696e646120486967687761792c51697869616e2c4e616e68616e6767616e6720526f61642c4a69",
                            "02:33:34.002 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---6e6875692c4c756e616e20526f61642c5368656e6475204869676877617900055368656e647520486967687761792c4c756e616e20526f61642c4a696e68",
                            "02:33:34.067 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---75692c4e616e68616e6767616e6720526f61642c51697869616e2c4a696e646120486967687761792c51696e676c616e6720526f61642c5869757a687520",
                            "02:33:34.131 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---526f61642c5869616e707520526f61642c44696e676b616e6720526f61642c4a696e68616920486967687761792c57616e677975616e20526f61642c4e61",
                            "02:33:34.164 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---6e7169616f204275732053746174696f6e0006000700080009007d88",
                            "02:33:55.785 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a410005010200007f0101020303c2b3c4cfc2b720b5bdc1cb2000576520617265206e6f77206172726976696e67206174204c756e616e20526f616420",
                            "02:33:55.794 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: sendList: 发送下行列表: []",
                            "02:33:55.800 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: sendBroadSite: 发送上行报站: 2 --- 00",
                            "02:33:55.805 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---0040c4",
                            "02:33:55.816 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a54a25ffff12",
                            "02:34:00.946 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a3b000501020000800101030303bdf0bbe320b5bdc1cb2000576520617265206e6f77206172726976696e67206174204a696e687569200049c7",
                            "02:34:00.955 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: sendBroadSite: 发送上行报站: 3 --- 00",
                            "02:34:01.004 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a54a25ffff12",
                            "02:34:04.570 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a55a49000501020000810101040303c4cfd0d0b8dbc2b720b5bdc1cb2000576520617265206e6f77206172726976696e67206174204e616e68616e676761",
                            "02:34:04.585 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---6e6720526f616420008e6b",
                            "02:34:04.607 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---a54a25ffff12",
                            "02:35:55.665 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---7e430010000054494d45180b0b011503356ca47e",
                            "02:45:55.419 D/L [Thread-11, com.yunbiao.ybbusstopplate.refactoring.utils.L.d(L.java:20)]: <---7e430010000054494d45180b0b01150d354fab7e"
            };
            for (String string : strings) {
                Log.w(TAG, "test1: " + string);
                if(string.contains("<---")){
                    String hex = string.split("<---")[1];
                    hex = hex.replaceAll(" ", "");
                    byte[] bytes = Utils.hexToByteArray(hex);
                    try {
                        analyzing(null,new ComBean("",bytes,bytes.length));
                    } catch (Throwable e) {
                        Log.e(TAG, "test: ", e);
                    }
                }
            }
        }).start();
    }
}


// a55a
// 4a02
// 05
// 01
// 14
// 00
// 00
// 7e
// 01
// 00 b7eec6d6bfeccfdf2c20 00
// 01 31332c3133 00
// 02 c4cfc7c5c6fbb3b5d5be2ccdfbd4b0c2b72cbdf0baa3b9abc2b72cb6a8bfb5c2b72ccfcdc6d6c2b72cd0e3d6f1c2b72cc7e5c0cac2b72cbdf0b4f3b9abc2b72cc6ebcfcd2cc4cfd0d0b8dbc2b72cbdf0bbe32cc2b3c4cfc2b72cc9f2b6c5b9abc2b700
// 03 c9f2b6c5b9abc2b72cc2b3c4cfc2b72cbdf0bbe32cc4cfd0d0b8dbc2b72cc6ebcfcd2cbdf0b4f3b9abc2b72cc7e5c0cac2b72cd0e3d6f1c2b72ccfcdc6d6c2b72cb6a8bfb5c2b72cbdf0baa3b9abc2b72ccdfbd4b0c2b72cc4cfc7c5c6fbb3b5d5be00
// 04 4e616e7169616f204275732053746174696f6e2c57616e677975616e20526f61642c4a696e68616920486967687761792c44696e676b616e6720526f61642c5869616e707520526f61642c5869757a687520526f61642c51696e676c616e6720526f61642c4a696e646120486967687761792c51697869616e2c4e616e68616e6767616e6720526f61642c4a696e6875692c4c756e616e20526f61642c5368656e6475204869676877617900
// 05 5368656e647520486967687761792c4c756e616e20526f61642c4a696e6875692c4e616e68616e6767616e6720526f61642c51697869616e2c4a696e646120486967687761792c51696e676c616e6720526f61642c5869757a687520526f61642c5869616e707520526f61642c44696e676b616e6720526f61642c4a696e68616920486967687761792c57616e677975616e20526f61642c4e616e7169616f204275732053746174696f6e00
// 06 00
// 07 00
// 08 00
// 09 00
// 7d88